import * as React from 'react';
import classNames from 'classnames';
import 'codemirror/lib/codemirror.css';
import { UnControlled as RCodeMirror } from 'react-codemirror2';
import loaderConfigs from './config';

import styles from './index.module.less';

const defaultLanguage = 'javascript';

const CodeMirror = ({ children = [], className }) => {
  const editorRef = React.useRef(null);

  React.useEffect(() => {
    let language = defaultLanguage;
    if (className) {
      const splitArray = className.split('-');
      if (splitArray.length === 2) {
        language = splitArray[splitArray.length - 1];
      }
    }
    if (!loaderConfigs[language]) {
      language = defaultLanguage;
    }
    const languageConfig = loaderConfigs[language];
    const languageConfigKeys = Object.keys(languageConfig);
    // 异步加载mode、theme等模块
    const loadTasks = languageConfigKeys
      .map(key => {
        const loader = languageConfig[key];
        if (typeof loader === 'function') {
          return Promise.resolve(loader());
        }
        return null;
      })
      .filter(task => !!task);
    // 重新设置mode, 并刷新Editor
    Promise.all(loadTasks)
      .then(() => {
        const editor = editorRef.current;
        const { themeName } = languageConfig;
        editor.setOption('mode', language);
        // 设置主题
        themeName && editor.setOption('theme', themeName);
        editor && editor.refresh();
      })
      .catch(e => {
        console.error(e);
      });
  }, [className]);

  const codeMirrorProps = {
    value: children.join(''),
    editorDidMount: editor => {
      editorRef.current = editor;
    },
    options: {
      mode: defaultLanguage,
      lineNumbers: false,
      readOnly: 'nocursor',
      scrollbarStyle: 'null',
    },
  };

  const pageCls = classNames(styles.codeMirror, styles.codeWhite);

  return (
    <div className={pageCls}>
      <div className="code-wrap">
        <div className="code-wrap-inner">
          <div className="code-dots">
            <span className="dot dot-red" />
            <span className="dot dot-orange" />
            <span className="dot dot-green" />
          </div>
          <div className="code-area">
            <RCodeMirror {...codeMirrorProps} />
          </div>
        </div>
      </div>
    </div>
  );
};

export default React.memo(CodeMirror);
